// 合并要求

import React, { Component } from 'react';
import { Button, Balloon, Dialog } from '@teamix/ui';
import { YunxiaoIcon, Title } from '@alife/devops-ui';
import track from 'utils/track';
import UsersAvatar from '@alife/teamix-at-users-avatar';
import MarkdownIt from 'markdown-it';
import { getWebIdeUrl } from 'api';
import CodeScanInfo from 'pages/index/pages/project/pages/projectMergeRequestDetail/containers/components/codeScanInfo';
import { navigate, navigateOpen } from 'utils/router';
import sha1 from 'sha1';
import utils from 'utils';
import './index.scss';
import intl from '../../../../../../../../../locale';
import { getFeature } from 'utils/features';
const md = new MarkdownIt();
const prefix = 'mr-request-info';
const discussion_check_type = 'discussion';
export default class MrRequestInfo extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isDialogVisible: false,
    };

    this.intervalCnt = -1;
  }

  onDialogOpen = () => {
    this.setState({
      isDialogVisible: true,
    });
  };

  onDialogClose = () => {
    this.setState({
      isDialogVisible: false,
    });
  };

  goWebIde = (e, path) => {
    e.preventDefault();
    const { codeReviewDetail } = window.FORCE;
    getWebIdeUrl({
      filepath: path,
      branch: codeReviewDetail.sourceBranch,
      commit: '',
      line: '',
      column: '',
      type: 'conflict',
      merge_commit: codeReviewDetail.targetBranch,
      mergerequestId: codeReviewDetail.id,
    })
      .then((result) => {
        navigateOpen(result.endpoint);
      })
      .catch((err) => {
        console.error(err);
      });
  };

  conflictTipsDialogJsx() {
    const { codeReviewDetail } = this.props;

    return (
      <Dialog
        visible={this.state.isDialogVisible}
        onClose={this.onDialogClose}
        footer={false}
        title={intl.get({
          id: 'code-assets.components.mergeRequsetInfo.ConflictResolutionMethodReference',
          defaultMessage: '冲突解决方法参考',
        })}
        style={{ width: '500px' }}
      >
        <div
          style={{ margin: '-14px 0' }}
          /* eslint-disable */
          dangerouslySetInnerHTML={{
            __html:
              window.FORCE.locale !== 'en_US'
                ? md.render(
                    codeReviewDetail.source_type === 'COMMIT'
                      ? intl.get({
                          id: 'code-assets.components.mergeRequsetInfo.TheSourceBranchIsCommit',
                          defaultMessage: '源分支为COMMIT，请在线下合并',
                        })
                      : `
步骤1. fetch并切换到源分支

\`\`\`
git fetch origin

git checkout -b ${codeReviewDetail.source_branch} origin/${codeReviewDetail.source_branch}
\`\`\`

步骤2. 合并目标分支

\`\`\`
git merge origin/${codeReviewDetail.target_branch}
\`\`\`

步骤3. 解决冲突并push
        `,
                  )
                : md.render(
                    codeReviewDetail.source_type === 'COMMIT'
                      ? 'Source is COMMIT, please merge at local'
                      : `
Step 1. Fetch and checkout source branch

\`\`\`
git fetch origin

git checkout -b ${codeReviewDetail.source_branch} origin/${codeReviewDetail.source_branch}
\`\`\`

Step 2. Merge target branch

\`\`\`
git merge origin/${codeReviewDetail.target_branch}
\`\`\`

Step 3. Resolve conflicts and push
        `,
                  ),
          }}

          /* eslint-enable */
        />
      </Dialog>
    );
  }

  // 打开评论面板并过滤未关闭评论，同时打开第一个有未关闭的评论的文件
  goChangeTab = () => {
    const { codeReviewDetail, allComments = [] } = this.props.changesReducer;
    const { pathResource } = window.FORCE;
    const { openConversations } = utils.comments2Conversations(allComments);

    let path;
    let line;
    let side;
    const firstCommentDetail = openConversations[0] && openConversations[0][0];
    if (firstCommentDetail) {
      path = firstCommentDetail.path;
      line = firstCommentDetail.line;
      side = firstCommentDetail.side;
    }
    // 此处跳转简单处理，不区分过期与否，直接跳转文件
    if (path && side && line) {
      navigate(
        `/${pathResource.fullPath}/merge_request/${codeReviewDetail.id}/changes#file=${sha1(
          path,
        )}&line=${line}&side=${side}`,
      );
    } else {
      navigate(`/${pathResource.fullPath}/merge_request/${codeReviewDetail.id}/changes`);
    }
    this.props.openCommentPanel({
      isShowComment: true,
      curCommentStatus: 'open',
    });

    this.props.changeMrTabKey('changes');
  };

  renderRight = (item, unAssigneesForLeft) => {
    if (item.check_type === 'approver_number') {
      return (
        <div className="mr-request-list-item-right">
          {unAssigneesForLeft ? <UsersAvatar dataSource={unAssigneesForLeft} /> : null}
        </div>
      );
    }
    if (item.check_type === discussion_check_type) {
      const { allComments = [] } = this.props.changesReducer;
      const { openConversations } = utils.comments2Conversations(allComments);
      return (
        <div className="mr-request-list-item-right">
          <span className="fail-dot dot" />
          <span className="number">
            {intl.get(
              {
                id: 'code-assets.components.mergeRequsetInfo.OpenconversationslengthPending',
                defaultMessage: '{openConversationsLength} 条待解决',
              },
              { openConversationsLength: openConversations.length },
            )}
          </span>
          <Button
            type="primary"
            className="discuss-detail-btn"
            text
            onClick={() => {
              // track({
              //   action: 'goto_pipelinelog',
              //   page: 'Repo-MR',
              //   mr_id: codeReviewDetail.id,
              // });
              this.goChangeTab(item.id, item.state);
            }}
          >
            {intl.get({
              id: 'code-assets.components.mergeRequsetInfo.ViewDetails',
              defaultMessage: '查看详情',
            })}
          </Button>
        </div>
      );
    }

    return (
      <div className="mr-request-list-item-right">
        {item.unsatisfied_items.length ? (
          <span className="text-grey">（{item.unsatisfied_items.join(', ')}）</span>
        ) : null}
      </div>
    );
  };

  approveCheckResultListJsx() {
    const { assignees, approve_check_result } = this.props.codeReviewDetail;
    if (!approve_check_result) return null;

    let unAssigneesForLeft;
    if (assignees) {
      unAssigneesForLeft = assignees.filter((item) => {
        return item.status !== 'approved';
      });
      unAssigneesForLeft.forEach((item) => {
        if (item.avatar_url) item.avatarUrl = item.avatar_url;
      });
    }

    const { satisfied_check_results, unsatisfied_check_results } = approve_check_result;
    const satisfiedCheckData =
      satisfied_check_results &&
      satisfied_check_results.filter((item) => {
        return item.check_type !== 'code_scan';
      });
    const unsatisfiedCheckData =
      unsatisfied_check_results &&
      unsatisfied_check_results.filter((item) => {
        return item.check_type !== 'code_scan';
      });

    return (
      <div>
        {satisfiedCheckData &&
          satisfiedCheckData.map((item) => (
            <div className="mr-request-list-item">
              <div>
                <span className="mr-request-list-item-icon">
                  <YunxiaoIcon type="success-fill" style={{ color: '#1dc11d' }} />
                </span>
                <span>{item.check_name}</span>
              </div>
              <div className="mr-request-list-item-right">
                {item.satisfied_items.length ? (
                  <UsersAvatar
                    dataSource={item.satisfied_items.map((v) => {
                      try {
                        const curItem = JSON.parse(v);
                        curItem.avatarUrl = curItem.avatar_url;
                        return curItem;
                      } catch (e) {
                        return v;
                      }
                    })}
                  />
                ) : null}
              </div>
            </div>
          ))}

        {unsatisfiedCheckData &&
          unsatisfiedCheckData.map((item) => {
            return (
              <div className={`mr-request-list-item ${item.check_type}`}>
                <div>
                  <span className="mr-request-list-item-icon">
                    <YunxiaoIcon type="time-fill" style={{ color: '#8c8c8c' }} />
                  </span>
                  <span>{item.check_name}</span>
                </div>
                {this.renderRight(item, unAssigneesForLeft)}
              </div>
            );
          })}
      </div>
    );
  }

  // 获取卡点是否通过
  getRequiredBuildsJSX = () => {
    const { mergeRequestBuilds } = this.props;
    const requiredBuilds =
      mergeRequestBuilds.filter((item) => {
        return item.required;
      }) || [];
    if (!requiredBuilds.length) {
      return null;
    }
    // 未通过卡点
    const notPassRequiredbuilds =
      mergeRequestBuilds.filter((item) => {
        return item.required && item.state !== 'PASS' && item.state !== 'WARNING';
      }) || [];
    return (
      <div className="mr-request-list-item">
        <div>
          <span className="mr-request-list-item-icon">
            <YunxiaoIcon
              type={notPassRequiredbuilds.length ? 'time-fill' : 'success-fill'}
              style={{ color: notPassRequiredbuilds.length ? '#8c8c8c' : '#1dc11d' }}
            />
          </span>
          <span>
            {intl.get({
              id: 'code-assets.components.mergeRequsetInfo.AllAutomaticChecksThatRequire',
              defaultMessage: '需要卡点的自动化检查全部通过',
            })}
          </span>
        </div>
      </div>
    );
  };

  renderWebIdeBtn = () => {
    const { isArchive } = window.FORCE.pathResource;
    const { codeReviewDetail, ipSetting, project_clone_download } = this.props;

    if (!ipSetting) {
      return null;
    }

    if (ipSetting.ip_whitelist_enabled && ipSetting.scope === 'all') {
      return (
        <Balloon.Tooltip
          align="t"
          trigger={
            <Button type="normal" size="small" disabled style={{ marginRight: 8 }}>
              {intl.get({
                id: 'code-assets.components.mergeRequsetInfo.WeinanSolution',
                defaultMessage: 'WebIDE 解决',
              })}
            </Button>
          }
        >
          {intl.get({
            id: 'code-assets.components.mergeRequsetInfo.TheEnterpriseHasEnabledIp',
            defaultMessage: '企业已启用 IP 白名单严格管控，暂不支持使用 WebIDE',
          })}
        </Balloon.Tooltip>
      );
    } else if (
      project_clone_download?.httpCloneLimit?.state === 'disable' &&
      project_clone_download?.sshCloneLimit?.state === 'disable'
    ) {
      return (
        <Balloon.Tooltip
          align="t"
          trigger={
            <Button type="normal" size="small" disabled style={{ marginRight: 8 }}>
              WebIDE 解决
            </Button>
          }
        >
          已启用仓库克隆下载控制，暂不支持使用 WebIDE，请联系管理员处理
        </Balloon.Tooltip>
      );
    }

    if (isArchive === 'false') {
      return (
        <Button
          type="normal"
          size="small"
          component="a"
          onClick={(e) => {
            track({
              action: 'resolve_conflict_by_ide',
              page: 'Repo-MR',
              mr_id: codeReviewDetail.id,
            });

            this.goWebIde(e, '');
          }}
          style={{ marginRight: 8 }}
        >
          {intl.get({
            id: 'code-assets.components.mergeRequsetInfo.WeinanSolution',
            defaultMessage: 'WebIDE 解决',
          })}
        </Button>
      );
    }
    return null;
  };

  render() {
    const { isArchive } = window.FORCE.pathResource;
    const { codeReviewDetail, sourceBranchExist, targetBranchExist } = this.props;
    // 已归档或者分支删除，不显示
    if (isArchive !== 'false' || !(sourceBranchExist === 'true' && targetBranchExist === 'true')) {
      return null;
    }
    // 可以合并时
    if (
      codeReviewDetail.state === 'accepted' &&
      codeReviewDetail.mergeStatus === 'can_be_merged' &&
      codeReviewDetail.approve_check_result.unsatisfied_check_results.length === 0
    ) {
      return (
        <div className={`${prefix} success`}>
          <div className={`${prefix}-title`}>
            {getFeature('project.mr.info.yundou.show') &&
              <div className={`${prefix}-img`}>
                <img
                  alt={intl.get({
                    id: 'code-assets.components.mergeRequsetInfo.MergeRequirementsMet',
                    defaultMessage: '已达到合并要求',
                  })}
                  className={`${prefix}-yundou`}
                  src="https://img.alicdn.com/tfs/TB1GlGtIKL2gK0jSZFmXXc7iXXa-372-294.png"
                />
              </div>
            }
            <div className={`${prefix}-tip`}>
              {intl.get({
                id: 'code-assets.components.mergeRequsetInfo.MergeRequirementsHaveBeenMet',
                defaultMessage: '已达到合并要求，准备合并吧',
              })}
            </div>
          </div>
          {getFeature('project.mr.info.scan_info.show') && (
            <div>
              <CodeScanInfo {...this.props} />
            </div>
          )}
        </div>
      );
    }

    return (
      <div className={`${prefix} error noborder`}>
        <div className={`${prefix}-title`}>
          {
            getFeature('project.mr.info.yundou.show') ?
              <div className={`${prefix}-img`}>
                <img
                  alt={intl.get({
                    id: 'code-assets.components.mergeRequsetInfo.MergeRequirementsNotMet',
                    defaultMessage: '未达到合并要求',
                  })}
                  className={`${prefix}-yundou`}
                  src="https://img.alicdn.com/tfs/TB1ruuhIKL2gK0jSZPhXXahvXXa-372-294.png"
                />
              </div>
            :
            null
          }
          <div className={`${prefix}-tip`}>
            {intl.get({
              id: 'code-assets.components.mergeRequsetInfo.NotMeetingTheMergerRequirements',
              defaultMessage: '未达到合并要求，继续努力吧！',
            })}
          </div>
        </div>
        <div className="mr-request-list">
          {codeReviewDetail.mergeStatus === 'cannot_be_merged' ? (
            <div className="mr-request-list-item space-between">
              <div className="mr-confilct-tip">
                <Title
                  align="t"
                  trigger={
                    <span>
                      <span className="mr-request-list-item-icon">
                        <YunxiaoIcon type="time-fill" style={{ color: '#8c8c8c' }} />
                      </span>
                      <span>
                        {intl.get({
                          id: 'code-assets.components.mergeRequsetInfo.CodeConflicts',
                          defaultMessage: '代码存在冲突，',
                        })}
                      </span>
                      {/* 项目已归档时，不提供IDE解决支持 */}
                      <span className="conflict-desc">
                        {getFeature('project.mr.conflict.WebIDE.show') && isArchive === 'false'
                          ? intl.get({
                              id: 'code-assets.components.mergeRequsetInfo.YouCanUseAWeb',
                              defaultMessage: '可使用 Web 端编辑器或命令行解决冲突',
                            })
                          : intl.get({
                              id: 'code-assets.components.mergeRequsetInfo.YouCanUseTheCommand',
                              defaultMessage: '可使用命令行解决冲突',
                            })}
                      </span>
                    </span>
                  }
                >
                  <span>
                    <span>
                      {intl.get({
                        id: 'code-assets.components.mergeRequsetInfo.CodeConflicts',
                        defaultMessage: '代码存在冲突，',
                      })}
                    </span>
                    {/* 项目已归档时，不提供IDE解决支持 */}
                    <span className="conflict-desc">
                      {isArchive === 'false'
                        ? intl.get({
                            id: 'code-assets.components.mergeRequsetInfo.YouCanUseAWeb',
                            defaultMessage: '可使用 Web 端编辑器或命令行解决冲突',
                          })
                        : intl.get({
                            id: 'code-assets.components.mergeRequsetInfo.YouCanUseTheCommand',
                            defaultMessage: '可使用命令行解决冲突',
                          })}
                    </span>
                  </span>
                </Title>
              </div>
              <div className="mr-request-list-item-right">
                {getFeature('project.mr.conflict.WebIDE.show') && this.renderWebIdeBtn()}
                <Balloon.Tooltip
                  trigger={
                    <span>
                      <Button
                        type="normal"
                        size="small"
                        onClick={() => {
                          track({
                            action: 'resolve_conflict_by_cli',
                            page: 'Repo-MR',
                            mr_id: codeReviewDetail.id,
                          });

                          this.onDialogOpen();
                        }}
                      >
                        {intl.get({
                          id: 'code-assets.components.mergeRequsetInfo.LocalSolution',
                          defaultMessage: '本地解决',
                        })}
                      </Button>
                      {this.conflictTipsDialogJsx()}
                    </span>
                  }
                  align="t"
                  text={intl.get({
                    id: 'code-assets.components.mergeRequsetInfo.ForMoreInformationAboutHow',
                    defaultMessage: '点击了解冲突解决方法参考',
                  })}
                />
              </div>
            </div>
          ) : null}
          {(codeReviewDetail.state === 'opened' || codeReviewDetail.state === 'reopened') &&
            this.approveCheckResultListJsx()}
          {/* 扫描状态放在一起，去除原有 */}
          {/* {this.getRequiredBuildsJSX()} */}

          {getFeature('project.mr.info.scan_info.show') && (
            <CodeScanInfo {...this.props} />
          )}
        </div>
      </div>
    );
  }
}
